package main

// 实现切片的删除操作
func main() {
	//input1 := []int{1, 2, 3, 4, 5}
	//input2 := []string{"A", "B", "C", "D", "E"}
	//res1 := SliceDeleteV3[int](3, input1)
	//res2 := SliceDeleteV3[string](2, input2)
	//fmt.Println(res1)
	//fmt.Println(res2)
}

// SliceDeleteV1 实现基本的删除操作
func SliceDeleteV1(idx int, vals []int) []int {
	// 边界判断
	if idx < 0 || idx >= len(vals) {
		panic("非法下标")
	}
	res := append(vals[:idx], vals[idx+1:]...)
	return res
}

// SliceDeleteV2 考虑使用比较高性能的实现(尽量少的出现内存分配，元素复制)
// 避免了使用 append 函数来创建一个新的切片，
// 而是直接在原始切片上进行元素的移动，从而减少了内存分配和元素复制的操作。
func SliceDeleteV2(idx int, vals []int) []int {
	// 边界判断
	if idx < 0 || idx >= len(vals) {
		panic("非法下标")
	}
	//for i := idx; i < len(vals)-1; i++ {
	//	vals[i] = vals[i+1]
	//}
	// 使用 copy() 函数会将后续的元素向前移动一位，避免使用循环逐个移动元素，覆盖掉要删除的元素。
	copy(vals[idx:], vals[idx+1:])
	return vals[:len(vals)-1]
}

// SliceDeleteV3 改为泛型方法
func SliceDeleteV3[T any](idx int, vals []T) []T {
	// 边界判断
	if idx < 0 || idx >= len(vals) {
		panic("非法下标")
	}
	// 使用 copy() 函数会将后续的元素向前移动一位，避免使用循环逐个移动元素，覆盖掉要删除的元素。
	copy(vals[idx:], vals[idx+1:])
	return vals[:len(vals)-1]
}

// SliceDeleteV4 支持缩容，并设计缩容机制；
// 暂时没有思路
func SliceDeleteV4(idx int, vals []int) []int {
	return vals
}
